import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { catchError, tap, switchMap, filter, take } from 'rxjs/operators'; // Import filter and take
import { Router } from '@angular/router';
import { API_URL } from '../app.config'; 

@Injectable({
  providedIn: 'root'
})
export class HttpService {

  private apiUrl = API_URL; // API base URL
  private refreshTokenInProgress = false;
  private tokenRefreshedSource = new BehaviorSubject<boolean>(false);
  tokenRefreshed$ = this.tokenRefreshedSource.asObservable();

  constructor(private http: HttpClient, private router: Router) { }

  // 获取通用的请求头
  private getHeaders(): HttpHeaders {
    const token = localStorage.getItem('token');
    // Handle the null case
    const authToken = token ? `Bearer ${token}` : '';
    return new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': authToken
    });
  }

  // 处理错误
  private handleError(error: HttpErrorResponse) {
    if (error.status === 401) {
      // 如果是未授权错误，尝试刷新令牌
      return this.refreshToken().pipe(
        switchMap(() => {
          // 重新发起原来的请求
          if(!!error.url){
            return this.retryRequest(error.url);
          }else{
            return throwError(() => new Error('Request URL is missing'));

          }
          
        }),
        catchError(() => {
          // 如果刷新令牌失败，重定向到登录页面
          this.router.navigate(['/login']);
          return throwError(() => new Error('Session expired'));

        })
      );
    }
    return throwError(() => new Error(error.message || 'Something bad happened; please try again later.'));

  }

  // 尝试刷新令牌
  private refreshToken(): Observable<any> {
    if (this.refreshTokenInProgress) {
      return this.tokenRefreshed$.pipe(
        filter(result => result), // Now filter is recognized
        take(1)
      );
    }

    this.refreshTokenInProgress = true;

    const refreshToken = localStorage.getItem('refreshToken');
    const refreshTokenData = refreshToken ? { refreshToken } : {};

    return this.http.post<any>(
       `${this.apiUrl}/auth/refresh-token`, 
       refreshTokenData).pipe(
      tap((tokens: any) => {
        localStorage.setItem('token', tokens.accessToken);
        localStorage.setItem('refreshToken', tokens.refreshToken);
        this.tokenRefreshedSource.next(true);
        this.refreshTokenInProgress = false;
      }),
      catchError(() => {
        this.tokenRefreshedSource.next(false);
        this.refreshTokenInProgress = false;
        return throwError(() => new Error('Failed to refresh token'));

      })
    );
  }

  // 重试原来的请求
  private retryRequest(url: string): Observable<any> {
    const headers = this.getHeaders();
    return this.http.request('GET', url, { headers });
  }

  // GET 请求
  get<T>(endpoint: string): Observable<T> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.get<T>(url, { headers: this.getHeaders() })
      .pipe(
        tap(_ => console.log(`fetched ${endpoint}`)),
        catchError(this.handleError)
      );
  }

  // POST 请求
  post<T>(endpoint: string, data: any): Observable<T> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.post<T>(url, data, { headers: this.getHeaders() })
      .pipe(
        tap(_ => console.log(`posted ${endpoint}`)),
        catchError(this.handleError)
      );
  }

  // PUT 请求
  put<T>(endpoint: string, data: any): Observable<T> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.put<T>(url, data, { headers: this.getHeaders() })
      .pipe(
        tap(_ => console.log(`updated ${endpoint}`)),
        catchError(this.handleError)
      );
  }

  // DELETE 请求
  delete<T>(endpoint: string): Observable<T> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.delete<T>(url, { headers: this.getHeaders() })
      .pipe(
        tap(_ => console.log(`deleted ${endpoint}`)),
        catchError(this.handleError)
      );
  }
}